import { createElementVNode, createTextVNode } from "./vdom"

// 创建真实dom
function  createElm(vnode){
  let {tag,data,children,text} = vnode
  if(typeof tag === 'string'){
    vnode.el = document.createElement(tag) // 将真实节点与虚拟节点对应起来


    patchProps(vnode.el,data)
    children.forEach(child=>{
      vnode.el.appendChild(createElm(child))
    })
  }else{
    vnode.el = document.createTextNode(text)
  }
  return vnode.el
}

function patchProps(el, props){
  for(let key in props){

    if(key==='style'){
      for(let styleKey in props.style){
        el.style[styleKey] = props.style[styleKey]
      }
    }else{
      el.setAttribute(key,props[key])
    }
  }
}

function patch(oldVNode, vnode) {
  // 初次渲染流程
  const isRealElement  = oldVNode.nodeType
  if (isRealElement){
    const elm = oldVNode
    const parentElm = elm.parentNode
    let newElm = createElm(vnode)
    console.log(newElm)
    parentElm.insertBefore(newElm,elm.nextSibling)
    parentElm.removeChild(elm)

    return newElm
  }else{
    //diff 算法
  }
}


export function initLifecycle(Vue) {
  Vue.prototype._update = function (vnode) {
    const vm =this
    const el = vm.$el

    
    // patch既有初始化功能 又有更新的功能
    vm.$el = patch(el,vnode)

  }
  // _c('div',{},...children)
  Vue.prototype._c = function () { // 创建元素
   return createElementVNode(this, ...arguments)
  }
  // _v(text)
  Vue.prototype._v = function () { //处理纯文本text
    return createTextVNode(this, ...arguments)

  }
  Vue.prototype._s = function (value) { // 处理{{}}模板
  if(typeof value == 'object'){
    return JSON.stringify(value)
  }
  return value
  }

  Vue.prototype._render = function () {
    // 当渲染时会从实例中取值
    const vm = this
    return vm.$options.render.call(vm)
  }
}

export function mountComponent(vm, el) {
  // 1. 调render方法产生虚拟dom
  vm.$el = el

  vm._update(vm._render())

  // 2.根据虚拟dom产生真是dom

  //3. 插入到el
}


// 核心流程 1）创造响应式数据 2）模板转化为ast语法树
// 3）将ast语法树转化为render函数 4）后续每次数据更新可以只执行render函数 （无需再次执行ast转化过程）
// render函数会产生虚拟节点（使用响应式数据）
// 根据生成的虚拟节点创造真是的DOM